home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
QRZ! Ham Radio 8
/
QRZ Ham Radio Callsign Database - Volume 8.iso
/
pc
/
files
/
t_unix
/
j109lxa4.tar
/
main.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-06-04
|
44KB
|
2,015 lines
/* Main-level network program:
* initialization
* keyboard processing
* generic user commands
*
* Copyright 1991 Phil Karn, KA9Q
*/
#include <stdio.h>
#include <time.h>
#if defined(__TURBOC__) && defined(MSDOS)
#include <fcntl.h>
#include <dos.h>
#include <io.h>
#include <conio.h>
#include <ctype.h>
#include <dir.h>
#endif
#ifdef UNIX
#include <fcntl.h>
#endif
#include "global.h"
#include "config.h"
#ifdef ANSIPROTO
#include <stdarg.h>
#endif
#include "mbuf.h"
#include "timer.h"
#include "proc.h"
#include "iface.h"
#include "ip.h"
#include "tcp.h"
#include "udp.h"
#include "ax25.h"
#include "kiss.h"
#ifdef ETHER
#include "enet.h"
#endif
#include "netrom.h"
#include "ftpcli.h"
#include "telnet.h"
#include "tty.h"
#include "session.h"
#include "hardware.h"
#include "usock.h"
#include "socket.h"
#ifdef LZW
#include "lzw.h"
#endif
#include "cmdparse.h"
#include "commands.h"
#include "daemon.h"
#include "devparam.h"
#include "domain.h"
#include "files.h"
#include "main.h"
#include "mailbox.h"
#include "remote.h"
#include "trace.h"
#ifdef fprintf
#undef fprintf
#endif
#include "mailutil.h"
#include "smtp.h"
#include "version.h"
#undef BETA 1
#ifdef BSAHAX
#define BETA 1
#endif
#ifdef XSPAWN
#include "xspawn.h"
#endif
#ifndef UNIX
/* The following is from the Borland Runtime Library Version 3.0 :
* Copyright (c) 1987, 1990 by Borland International
*/
typedef struct
{
unsigned char windowx1;
unsigned char windowy1;
unsigned char windowx2;
unsigned char windowy2;
unsigned char attribute;
unsigned char normattr;
unsigned char currmode;
unsigned char screenheight;
unsigned char screenwidth;
unsigned char graphicsmode;
unsigned char snow;
union {
char far * p;
struct { unsigned off,seg; } u;
} displayptr;
} VIDEOREC;
extern VIDEOREC _video;
#endif
extern struct cmds DFAR Cmds[],DFAR Startcmds[],DFAR Stopcmds[],Attab[];
#if (!defined(MSDOS) || defined(ESCAPE)) /* PC uses F-10 key always */
static char Escape = 0x1d; /* default escape character is ^] */
#endif
#ifdef __TURBOC__
int dofstat __ARGS((void));
#endif
static char Prompt[] = "net> ";
char NoRead[] = "Can't read %s: %s\n";
char Badhost[] = "Unknown host %s\n";
char Badinterface[] = "Interface \"%s\" unknown\n";
char Existingiface[] = "Interface %s already exists\n";
char Nospace[] = "No space!!\n"; /* Generic malloc fail message */
char Nosversion[] = "KA9Q NOS version %s\n";
#ifdef MSDOS
char NosLoadInfo[] = "NOS load info: CS=0x%04x DS=0x%04x";
#endif
char Noperm[] = "Permission denied.\n";
char Nosock[] = "Can't create socket\n";
char SysopBusy[] = "The sysop is busy. Try again later.\n";
char *Hostname;
char *Motd; /* Message Of The Day */
int Attended = TRUE; /* default to attended mode */
int ThirdParty = TRUE; /* Allows 3rd party mail by default */
int main_exit; /* from main program (flag) */
int DosPrompt; /* Use a dos-like prompt */
int Mprunning; /* flag for other parts (domain) to signal
* that we are fully configured running.
*/
struct proc *Cmdpp;
#ifndef UNIX
struct proc *Display;
#endif
#ifdef LZW
int Lzwmode = LZWCOMPACT;
int16 Lzwbits = LZWBITS;
#endif
#ifdef TRACE
int Tracesession = 1;
struct session *Trace = NULLSESSION;
#endif
static char *DumpAddr = NULL; /* Memory dump pointer */
static FILE *Logfp;
time_t StartTime; /* Time that NOS was started */
static int Verbose;
static void ctohex __ARGS((char *buf,int16 c));
static void fmtline __ARGS((int16 addr,char *buf,int16 len));
extern void assign_filenames __ARGS((char *));
static void logcmd __ARGS((char *));
#if 0
void status();
#endif
int Numrows,Numcols; /* screen size at startup - WG7J */
struct hist *Histry; /* command recall stuff */
int Histrysize;
int Maxhistory = 10;
#ifdef UNIX
static char **origargv;
#endif
int
#ifdef PROTOTYPES
main(int argc, char **argv)
#else
main(argc,argv)
int argc;
char *argv[];
#endif
{
char *inbuf,*intmp;
FILE *fp;
struct daemon *tp;
struct mbuf *bp;
int c;
#ifdef UNIX
int no_itimer, did_init;
char *trace_sm = 0;
char *def_sm = 0;
static int oops;
#else
struct text_info ti;
#endif
struct cur_dirs dirs;
#ifdef UNIX
if (oops++)
{
iostop();
fprintf(stderr, "NOS PANIC: NOS main re-entered.\n");
fflush(stderr);
fflush(stdout);
kill(getpid(), 11);
}
origargv = argv;
#endif
#ifdef XSPAWN
/* These vectors WILL be intercepted by NOS in COMMAND.ASM
Go ahead and tell XSPAWN to save their current state, now.
Vector 0x23 is also used by NOS, but is ALREADY being preserved
by the XSPAWN routines */
addvect (8, CURRENT);
addvect (0x10, CURRENT);
addvect (0x13, CURRENT);
addvect (0x1b, CURRENT);
addvect (0x21, CURRENT);
addvect (0x24, CURRENT);
addvect (0x28, CURRENT);
#endif
setversion();
StartTime = time(&StartTime); /* NOS Start_Up time */
#ifdef UNIX
SRANDOM((getpid() << 16) ^ time((long *) 0));
#else
randomize();
#endif
#ifdef UNIX
no_itimer = 0;
#else
/* Borland's library calls int10. Some vga mode utilities do not
* report the screen sizes correctly into the internal _video structure.
* This can cause the screen size to be faulty in the gettextinfo call.
* Instead, read the BIOS data area to get the correct screen info,
* and update the _video structure for later calls to
* gettextinfo(), clrscr(), etc... - WG7J
*
* If this doesn't work, you can now overwrite the values with
* the -r and -c command line options - WG7J
*/
Numrows = (int) *(char far *)MK_FP(0x40,0x84) + 1;
gettextinfo(&ti);
Numcols = ti.screenwidth;
/*
Numrows = ti.screenheight;
*/
if(Numrows == 1)
Numrows = 25;
#endif
#ifdef UNIX
did_init = 0;
while((c = getopt(argc,argv,"s:d:x:f:nbvDS:T:")) != EOF){
#else
while((c = getopt(argc,argv,"s:d:r:c:x:f:nbvD")) != EOF){
#endif
switch(c){
#ifdef TRACE
case 'n':
Tracesession = 0; /* No session for tracing */
break;
#endif
#ifndef UNIX
case 'r': /* Number of rows on screen */
Numrows = atoi(optarg);
break;
case 'c': /* Number of columns on screen */
Numcols = atoi(optarg);
break;
#endif
case 's': /* Number of sockets */
Nusock = atoi(optarg);
break;
#ifdef XSPAWN
case 'x': /* Path for XSWAP temp file */
_swappath = strdup(optarg);
break;
#endif
#if defined(MSDOS) || defined(UNIX)
case 'f':
assign_filenames(optarg);
#ifdef UNIX
did_init = 1;
#endif
break;
#endif
case 'd': /* Root directory for various files */
initroot(optarg);
break;
#ifdef __TURBOC__
case 'b': /* Use BIOS for screen output */
directvideo = 0;
break;
#endif
case 'v':
Verbose = 1;
break;
#ifdef UNIX
case 'D':
no_itimer = 1; /* for debugging */
break;
case 'S':
if (sm_lookup(optarg, 0))
def_sm = optarg;
else
printf("No session manager \"%s\", using default\n", optarg);
break;
case 'T':
if (sm_lookup(optarg, 0))
trace_sm = optarg;
else
printf("Session manager for trace not found, using default\n");
break;
#endif
}
}
#ifdef UNIX
if (!did_init)
assign_filenames(".nosrc");
#endif
#ifndef UNIX
/* Set the internal structure, in case there was a command
* line overwrite - WG7J
*/
_video.screenheight = (unsigned char)Numrows;
_video.windowx2 = (unsigned char)(Numcols - 1);
_video.windowy2 = (unsigned char)(Numrows - 1);
#endif
kinit();
ipinit();
#ifdef UNIX
ioinit(no_itimer);
#else
ioinit();
#endif
sockinit();
Cmdpp = mainproc("cmdintrp");
Sessions = (struct session *)callocw(Nsessions,sizeof(struct session));
#ifdef TRACE
if(Tracesession)
#ifdef UNIX
{
if (!trace_sm)
trace_sm = Trace_sessmgr;
Trace = sm_newsession(trace_sm, NULLCHAR, TRACESESSION, 0);
}
#else
Trace = newsession(NULLCHAR,TRACESESSION,0);
#endif
#endif
#ifdef UNIX
if (!def_sm)
def_sm = Command_sessmgr;
Command = Lastcurr = sm_newsession(def_sm, NULLCHAR, COMMAND, 0);
#else
Command = Lastcurr = newsession(NULLCHAR,COMMAND,0);
#endif
/* Flow mode is set AFTER we've read the autoexec file !
* this keeps systems from locking up if the reboot is unattended - WG7J
*/
#ifndef UNIX
Display = newproc("display",250,display,0,NULLCHAR,NULL,0);
#endif
tprintf(Nosversion,Version);
tputs(Version2);
tputs("Copyright 1991 by Phil Karn (KA9Q) and contributors.\n");
#ifdef BETA
tputs("This is a BETA version; be warned !\n");
#endif
rflush();
/* Start background Daemons */
for(tp=Daemons;;tp++){
if(tp->name == NULLCHAR)
break;
newproc(tp->name,tp->stksize,tp->fp,0,NULLCHAR,NULL,0);
}
init_dirs(&dirs);
Command->curdirs=&dirs;
if(optind < argc){
/* Read startup file named on command line */
if((fp = fopen(argv[optind],READ_TEXT)) == NULLFILE)
tprintf(NoRead,argv[optind],sys_errlist[errno]);
} else {
/* Read default startup file named in files.c (autoexec.nos) */
if((fp = fopen(Startup,READ_TEXT)) == NULLFILE)
tprintf(NoRead,Startup,sys_errlist[errno]);
}
if(fp != NULLFILE){
inbuf = mallocw(BUFSIZ);
intmp = mallocw(BUFSIZ);
while(fgets(inbuf,BUFSIZ,fp) != NULLCHAR){
strcpy(intmp,inbuf);
if(Verbose){
tprintf("%s",intmp);
rflush();
}
if(cmdparse(Cmds,inbuf,NULL) != 0){
tprintf("input line: %s",intmp);
rflush();
}
}
fclose(fp);
free(inbuf);
free(intmp);
}
Mprunning = 1; /* we are on speed now */
Command->flowmode = 1; /* set 'more' paging on command screen */
/* Now loop forever, processing commands */
for(;;){
if(DosPrompt)
tprintf("%s ",dirs.dir);
tputs(Prompt);
usflush(Command->output);
if(recv_mbuf(Command->input,&bp,0,NULLCHAR,0) != -1){
logcmd(bp->data);
(void)cmdparse(Cmds,bp->data,Lastcurr);
free_p(bp);
}
}
}
/* Keyboard input process */
/* Modified to support F-key session switching,
* from the WNOS3 sources - WG7J
*/
void
keyboard(i,v1,v2)
int i;
void *v1;
void *v2;
{
int c;
struct mbuf *bp;
register int j,k;
struct session *sp;
/* Keyboard process loop */
for(;;){
c = kbread();
#if (!defined(MSDOS) || defined(ESCAPE))
if(c == Escape && Escape != 0)
c = -2;
#endif
if(c == -2 && Current != Command){
/* Save current tty mode and set cooked */
swapscreen(Current,Command);
Lastcurr = Current;
Current = Command;
/* set 'more' paging on command screen */
Command->flowmode = 1;
}
if((c < -2) && (c > -12)) { /* F1 to F9 pressed */
#ifdef TRACE
/* If F9 is pressed, -11 is returned and we swap to Trace - WG7J */
if(c == -11) {
if(Tracesession) {
if(Current != Trace){
/* Save current tty mode and set cooked */
swapscreen(Current,Trace);
Lastcurr = Current;
Current = Trace;
/* turn off 'more' paging on trace screen */
Trace->flowmode = 0;
} else {
/* Toggle back to previous session */
swapscreen(Trace,Lastcurr);
Current = Lastcurr;
Lastcurr = Trace;
}
}
} else {
#endif
k = (-1 * c) - 2;
for(sp = Sessions, j = 0; sp < &Sessions[Nsessions]; sp++) {
if(sp->type == COMMAND)
continue;
j++;
if(sp->type != FREE && j == k) {
swapscreen(Current,sp);
Lastcurr = Current;
Current = sp;
break;
}
}
#ifdef TRACE
}
#endif
}
Current->row = Numrows;
psignal(&Current->row,1);
if(c >= 0){
#ifdef UNIX
if (Current->morewait) /* end display pause, if any */
Current->morewait = 2;
#endif
/* If the screen driver was in morewait state, this char
* has woken him up. Toss it so it doesn't also get taken
* as normal input. If the char was a command escape,
* however, it will be accepted; this gives the user
* a way out of lengthy output.
*/
if(!Current->morewait
&& (bp = ttydriv(Current,c)) != NULLBUF){
send_mbuf(Current->input,bp,0,NULLCHAR,0);
}
}
}
}
extern int Kblocked;
extern char *Kbpasswd;
#ifdef LOCK
/*Lock the keyboard*/
int
dolock(argc,argv,p)
int argc;
char *argv[];
void *p;
{
extern char Noperm[];
/*allow only keyboard users to access the lock command*/
if(Curproc->input != Command->input) {
tputs(Noperm);
return 0;
}
if(argc == 1) {
if(Kbpasswd == NULLCHAR)
tputs("Set password first\n");
else {
Kblocked = 1;
tputs("Keyboard locked\n");
Command->ttystate.echo = 0; /* Turn input echoing off! */
}
return 0;
}
if(argc == 3) {
if(*argv[1] == 'p') { /*set the password*/
if(Kbpasswd != NULLCHAR){
free(Kbpasswd);
Kbpasswd = NULLCHAR; /* reset the pointer */
}
if(!strlen(argv[2]))
return 0; /* clearing the buffer */
Kbpasswd = strdup(argv[2]);
return 0;
}
}
tputs("Usage: lock password \"<unlock password>\"\n"
"or 'lock' to lock the keyboard\n");
return 0;
}
#endif
#ifdef ALLCMD
/* Standard commands called from main */
int
dodelete(argc,argv,p)
int argc;
char *argv[];
void *p;
{
int i;
char fname[128];
for(i=1;i < argc; i++){
strcpy(fname,make_fname(Command->curdirs->dir,argv[i]));
if(unlink(fname) == -1){
tprintf("Can't delete %s: %s\n",fname,sys_errlist[errno]);
}
}
return 0;
}
int
dorename(argc,argv,p)
int argc;
char *argv[];
void *p;
{
char fname1[128];
char fname2[128];
strcpy(fname1,make_fname(Command->curdirs->dir,argv[1]));
strcpy(fname2,make_fname(Command->curdirs->dir,argv[2]));
if(rename(fname1,fname2) == -1)
tprintf("Can't rename: %s\n",sys_errlist[errno]);
return 0;
}
int
docopy(argc,argv,p)
int argc;
char *argv[];
void *p;
{
FILE *old, *new;
int ch;
unsigned char count;
char fname[128];
strcpy(fname,make_fname(Command->curdirs->dir,argv[1]));
if((old = fopen(fname,"rb")) == NULL) {
tprintf("Can't open %s: %s\n",fname,sys_errlist[errno]);
return 1;
}
strcpy(fname,make_fname(Command->curdirs->dir,argv[2]));
if((new = fopen(fname,"wb")) == NULL) {
tprintf("Can't open %s: %s\n",fname,sys_errlist[errno]);
fclose(old);
return 1;
}
/* Now go copy */
count = 0;
while((ch = fgetc(old)) != EOF) {
fputc(ch,new);
if(!(++count)) /* be polite to other users */
pwait(NULL);
}
fclose(old);
fclose(new);
return 0;
}
#endif /*ALLCMD*/
/*this is also called from the remote-server for the 'exit' command - WG7J*/
void
where_outta_here(resetme)
int resetme;
{
time_t StopTime;
FILE *fp;
char *inbuf,*intmp;
/* Execute sequence of commands taken from file "~/onexit.nos" */
/* From iw0cnb */
if((fp = fopen(Onexit,READ_TEXT)) != NULLFILE){
inbuf = mallocw(BUFSIZ);
intmp = mallocw(BUFSIZ);
while(fgets(inbuf,BUFSIZ,fp) != NULLCHAR){
strcpy(intmp,inbuf);
if(Verbose){
tprintf("%s",intmp);
rflush();
}
if(cmdparse(Cmds,inbuf,NULL) != 0){
tprintf("input line: %s",intmp);
}
}
fclose(fp);
free(inbuf);
free(intmp);
}
StopTime = time(&StopTime);
main_exit = TRUE; /* let everyone know we're out of here */
reset_all();
if(Dfile_updater != NULLPROC)
alert(Dfile_updater,0); /* don't wait for timeout */
pause(3000); /* Let it finish */
#ifdef TRACE
shuttrace();
#endif
log(-1,"NOS was stopped");
if(Logfp){
fclose(Logfp);
Logfp = NULLFILE;
}
#ifdef UNIX
detach_all_asy(); /* make sure everything is unlocked */
pwait(NULL);
#endif
iostop();
if(resetme)
#ifdef UNIX
{
if (fork() == 0)
abort();
execvp(origargv[0], origargv); /* re-run NOS */
}
#else
sysreset();
#endif
exit(0);
}
#if 0
extern struct proc *Aproc;
#endif
int
doexit(argc,argv,p)
int argc;
char *argv[];
void *p;
{
time_t nowtime, elapsedtime;
unsigned int days,hrs,mins,secs;
#if 0 /* you can't have 2 at's at the same time?? */
if(Curproc == Aproc) /* From the AT command */
#endif
if (strnicmp(Curproc->name, "at ", 3) == 0)
where_outta_here(0);
if(Curproc->input == Command->input) { /* From keyboard */
Command->ttystate.edit = Command->ttystate.echo = 0;
if(toupper(keywait("Are you sure? ",0))=='Y') {
nowtime = time(&nowtime); /* current time */
elapsedtime = nowtime - StartTime; /* nos elapsed time */
secs = elapsedtime % 60;
elapsedtime = elapsedtime / 60;
mins = elapsedtime % 60;
elapsedtime = elapsedtime / 60;
hrs = elapsedtime % 24;
elapsedtime = elapsedtime / 24;
days = elapsedtime;
tprintf("NOS Exiting - Runtime => %u days:%02u hours:%02u minutes:%02u seconds.\n",days,hrs,mins,secs);
where_outta_here(0); /*No reset!*/
}
Command->ttystate.edit = Command->ttystate.echo = 1;
return 0;
}
/* Anything else; probably mailbox-sysop */
return -2;
}
extern char Chostname[];
int
dohostname(argc,argv,p)
int argc;
char *argv[];
void *p;
{
#ifdef CONVERS
char *cp;
#endif
if(argc < 2)
tprintf("%s\n",Hostname);
else {
struct iface *ifp;
char *name;
if((ifp = if_lookup(argv[1])) != NULLIF){
if((name = resolve_a(ifp->addr, FALSE)) == NULLCHAR){
tprintf("Interface address not resolved\n");
return 1;
} else {
if(Hostname != NULLCHAR)
free(Hostname);
Hostname = name;
tprintf("Hostname set to %s\n", name );
}
} else {
if(Hostname != NULLCHAR)
free(Hostname);
Hostname = strdup(argv[1]);
/* Remove trailing dot */
if(Hostname[strlen(Hostname)] == '.')
Hostname[strlen(Hostname)] = '.';
}
#ifdef CONVERS
/* If convers hostname not set yet, set it to first 10 chars
* of the hostname. If there are '.' from the right, cut off
* before that. - WG7J
*/
if(Chostname[0] == '\0') {
strncpy(Chostname,Hostname,CNAMELEN);
if((cp = strrchr(Chostname,'.')) != NULLCHAR)
*cp = '\0';
}
#endif
}
return 0;
}
int
dolog(argc,argv,p)
int argc;
char *argv[];
void *p;
{
static char *logname;
if(argc < 2){
if(Logfp)
tprintf("Logging to %s\n",logname);
else
tprintf("Logging off\n");
return 0;
}
if(Logfp){
log(-1,"NOS log closed");
fclose(Logfp);
Logfp = NULLFILE;
free(logname);
logname = NULLCHAR;
}
if(strcmp(argv[1],"stop") != 0){
logname = strdup(argv[1]);
Logfp = fopen(logname,APPEND_TEXT);
log(-1,"NOS v%s was started at %s", Version, ctime(&StartTime));
#ifdef MSDOS
log(-1,NosLoadInfo, _CS, _DS);
#endif
}
return 0;
}
int
dohelp(argc,argv,p)
int argc;
char *argv[];
void *p;
{
register struct cmds *cmdp;
int i;
char buf[66];
tprintf("Main commands:\n");
memset(buf,' ',sizeof(buf));
buf[64] = '\n';
buf[65] = '\0';
for(i=0,cmdp = Cmds;cmdp->name != NULL;cmdp++,i = (i+1)%4){
strncpy(&buf[i*16],cmdp->name,strlen(cmdp->name));
if(i == 3){
tprintf(buf);
memset(buf,' ',sizeof(buf));
buf[64] = '\n';
buf[65] = '\0';
}
}
if(i != 0)
tprintf(buf);
return 0;
}
/* Attach an interface
* Syntax: attach <hw type> <I/O address> <vector> <mode> <label> <bufsize> [<speed>]
*/
int
doattach(argc,argv,p)
int argc;
char *argv[];
void *p;
{
return subcmd(Attab,argc,argv,p);
}
/* Manipulate I/O device parameters */
int
doparam(argc,argv,p)
int argc;
char *argv[];
void *p;
{
int param,set;
int32 val;
register struct iface *ifp;
if((ifp = if_lookup(argv[1])) == NULLIF){
tprintf(Badinterface,argv[1]);
return 1;
}
if(ifp->ioctl == NULL){
tprintf("Not supported\n");
return 1;
}
if(argc < 3){
for(param=1;param<=16;param++){
val = (*ifp->ioctl)(ifp,param,FALSE,0L);
if(val != -1)
tprintf("%s: %ld\n",parmname(param),val);
}
return 0;
}
param = devparam(argv[2]);
if(param == -1){
tprintf("Unknown parameter %s\n",argv[2]);
return 1;
}
if(argc < 4){
set = FALSE;
val = 0L;
} else {
set = TRUE;
val = atol(argv[3]);
}
val = (*ifp->ioctl)(ifp,param,set,val);
if(val == -1){
tprintf("Parameter %s not supported\n",argv[2]);
} else {
tprintf("%s: %ld\n",parmname(param),val);
}
return 0;
}
/* Display or set IP interface control flags */
int
domode(argc,argv,p)
int argc;
char *argv[];
void *p;
{
register struct iface *ifp;
if((ifp = if_lookup(argv[1])) == NULLIF){
tprintf(Badinterface,argv[1]);
return 1;
}
if(argc < 3){
tprintf("%s: %s\n",ifp->name,
(ifp->flags & CONNECT_MODE) ? "VC mode" : "Datagram mode");
return 0;
}
switch(argv[2][0]){
case 'v':
case 'c':
case 'V':
case 'C':
ifp->flags |= CONNECT_MODE;
break;
case 'd':
case 'D':
ifp->flags &= ~CONNECT_MODE;
break;
default:
tprintf("Usage: %s [vc | datagram]\n",argv[0]);
return 1;
}
return 0;
}
#if (!defined(MSDOS) || defined(ESCAPE))
int
doescape(argc,argv,p)
int argc;
char *argv[];
void *p;
{
if(argc < 2)
tprintf("0x%x\n",Escape);
else
Escape = *argv[1];
return 0;
}
#endif MSDOS
/* Generate system command packet. Synopsis:
* remote [-p port#] [-k key] [-a hostname] <hostname> reset|exit|kickme
*/
int
doremote(argc,argv,p)
int argc;
char *argv[];
void *p;
{
struct sockaddr_in fsock;
int s,c;
char *data,x;
int16 port,len;
char *key = NULLCHAR;
int klen;
int32 addr = 0;
char *cmd,*host;
port = IPPORT_REMOTE; /* Set default */
optind = 1; /* reinit getopt() */
#ifdef __GNUC__
klen = 0; /* defeat spurious "uninitialized" warning */
#endif
while((c = getopt(argc,argv,"a:p:k:s:")) != EOF){
switch(c){
case 'a':
if((addr = resolve(optarg)) == 0){
tprintf(Badhost,optarg);
return -1;
}
break;
case 'p':
port = atoi(optarg);
break;
case 'k':
key = optarg;
klen = strlen(key);
break;
case 's':
Rempass = strdup(optarg);
return 0; /* Only set local password */
}
}
if(optind > argc - 2){
tprintf("Insufficient args\n");
return -1;
}
host = argv[optind++];
cmd = argv[optind];
if((s = socket(AF_INET,SOCK_DGRAM,0)) == -1){
tprintf("socket failed\n");
return 1;
}
len = 1;
/* Did the user include a password or kickme target? */
if(addr != 0 && cmd[0] == 'k')
len += sizeof(int32);
if(key != NULLCHAR && (cmd[0] == 'r' || cmd[0] == 'e'))
len += klen;
if(len == 1)
data = &x;
else
data = mallocw((size_t)len);
fsock.sin_family = AF_INET;
if((fsock.sin_addr.s_addr = resolve(host)) == 0){
tprintf(Badhost,host);
goto cleanup;
}
fsock.sin_port = port;
switch(cmd[0]){
case 'r':
data[0] = SYS_RESET;
if(key != NULLCHAR)
strncpy(&data[1],key,(size_t)klen);
break;
case 'e':
data[0] = SYS_EXIT;
if(key != NULLCHAR)
strncpy(&data[1],key,(size_t)klen);
break;
case 'k':
data[0] = KICK_ME;
if(addr != 0)
put32(&data[1],addr);
break;
default:
tprintf("Unknown command %s\n",cmd);
goto cleanup;
}
/* Form the command packet and send it */
if(sendto(s,data,len,0,(char *)&fsock,sizeof(fsock)) == -1){
tprintf("sendto failed: %s\n",sys_errlist[errno]);
goto cleanup;
}
cleanup:
if(data != &x)
free(data);
close_s(s);
return 0;
}
#if (defined(ALLCMD) || defined(ALLSESSIONS))
int
morecmd(argc,argv,p)
int argc;
char *argv[];
void *p;
{
struct session *sp;
FILE *fp;
char buf[81],fname[128];
int row;
int usesession = 0;
/* Use a session if this comes from console - WG7J*/
#ifdef __GNUC__
row = 0; /* defeat uninitialized warnings */
sp = 0;
#endif
if(Curproc->input == Command->input) {
usesession = 1;
if((sp = newsession(argv[1],MORE,0)) == NULLSESSION){
return 1;
}
/* Put tty into raw mode so single-char responses will work */
sp->ttystate.echo = sp->ttystate.edit = 0;
row = Numrows - 1;
}
strcpy(fname,make_fname(Command->curdirs->dir,argv[1]));
if((fp = fopen(fname,READ_TEXT)) == NULLFILE){
tprintf(NoRead,fname,sys_errlist[errno]);
if(usesession) {
keywait(NULLCHAR,1);
freesession(sp);
}
return 1;
}
while(fgets(buf,sizeof(buf),fp),!feof(fp)){
if((argc < 3) || (strstr(buf,argv[2])!=NULLCHAR)) {
tprintf("%s",buf);
if(usesession) {
if(row > 0 && --row == 0){
row = keywait("--More--",0);
switch(row){
case -1:
case 'q':
case 'Q':
goto done;
case '\n':
case '\r':
row = 1;
break;
case ' ':
default:
row = Numrows - 1;
}
}
}
}
}
done: fclose(fp);
if(usesession) {
keywait(NULLCHAR,1);
freesession(sp);
}
return 0;
}
int
domore(argc,argv,p)
int argc;
char *argv[];
void *p;
{
char **pargv;
int i;
if(Curproc->input == Command->input) {
/* Make private copy of argv and args,
* spawn off subprocess and return.
*/
pargv = (char **)callocw((size_t)argc,sizeof(char *));
for(i=0;i<argc;i++)
pargv[i] = strdup(argv[i]);
newproc("more",512,(void (*)__ARGS((int,void *,void *)))morecmd,argc,(void *)pargv,p,1);
} else
morecmd(argc,argv,p);
return 0;
}
#endif
#ifdef ALLCMD
int
dotail(argc,argv,p)
int argc;
char *argv[];
void *p;
{
register int handle, i;
register unsigned line = 0, rdsize = 2000;
long length;
char *buffer;
buffer = callocw(2000, sizeof (char));
if ((handle = open (argv[1], O_BINARY | O_RDONLY)) == -1) {
tprintf(NoRead,argv[1],sys_errlist[errno]);
free(buffer);
return -1;
}
length = filelength(handle);
if (length > 2000) {
length -= 2000;
} else {
rdsize = (int) length;
length = 0;
}
lseek (handle, length, SEEK_SET);
if (read (handle, buffer, rdsize) == -1) {
tprintf(NoRead,argv[1],sys_errlist[errno]);
close(handle);
free(buffer);
return -1;
}
for (i = rdsize - 1; i > 0; i--) {
if (buffer[i] == '\n')
line++;
if (line == 18)
break;
}
for (; i < rdsize; i++)
tputc(buffer[i]);
tprintf("\n");
close(handle);
free(buffer);
return 0;
}
#endif /*ALLCMD*/
/* No-op command */
int
donothing(argc,argv,p)
int argc;
char *argv[];
void *p;
{
return 0;
}
static int SendError = 1;
int doerror(int argc,char *argv[],void *p) {
return setbool(&SendError,"Mail errors",argc,argv);
}
/* Mail a system message to the sysop - WG7J */
void
mail_error(char *fmt, ...)
{
FILE *wrk,*txt;
va_list ap;
char *cp;
long t,msgid;
char fn[128];
if(!SendError)
return;
/* Get current time */
time(&t);
/* get the message id for this message */
msgid = get_msgid();
/* Create the smtp work file */
sprintf(fn,"%s/%ld.wrk",Mailqdir,msgid);
if((wrk = fopen(fn,"w")) == NULL)
return;
/* Create the smtp text file */
sprintf(fn,"%s/%ld.txt",Mailqdir,msgid);
if((txt = fopen(fn,"w")) == NULL) {
fclose(wrk);
return;
}
/* Fill in the work file */
fprintf(wrk,"%s\nMAILER-DAEMON@%s\nsysop@%s",Hostname,Hostname,Hostname);
fclose(wrk);
/* Fill in the text file headers */
fprintf(txt,"%s%s",Hdrs[DATE],ptime(&t));
fprintf(txt,"%s<%ld@%s>\n",Hdrs[MSGID],msgid,Hostname);
fprintf(txt,"%sMAILER-DAEMON@%s\n",Hdrs[FROM],Hostname);
fprintf(txt,"%ssysop@%s\n",Hdrs[TO],Hostname);
fprintf(txt,"%sSystem message\n\n",Hdrs[SUBJECT]);
/* Print the text body */
cp = ctime(&t);
fprintf(txt,"On %s",cp);
va_start(ap,fmt);
vfprintf(txt,fmt,ap);
va_end(ap);
fprintf(txt,"\n");
fclose(txt);
/* Now kick the smtp server */
smtptick(NULL);
}
/* Log messages of the form
* Tue Jan 31 00:00:00 1987 44.64.0.7:1003 open FTP
*/
#if defined(ANSIPROTO)
void
log(int s,char *fmt, ...)
{
va_list ap;
char *cp;
long t;
int i;
struct sockaddr fsocket;
#ifdef MSDOS
int fd;
#endif
if(Logfp == NULLFILE)
return;
time(&t);
cp = ctime(&t);
rip(cp);
i = SOCKSIZE;
fprintf(Logfp,"%s",cp);
if(getpeername(s,(char *)&fsocket,&i) != -1)
fprintf(Logfp," %s",psocket(&fsocket));
fprintf(Logfp," - ");
va_start(ap,fmt);
vfprintf(Logfp,fmt,ap);
va_end(ap);
fprintf(Logfp,"\n");
fflush(Logfp);
#ifdef MSDOS
/* MS-DOS doesn't really flush files until they're closed */
fd = fileno(Logfp);
if((fd = dup(fd)) != -1)
close(fd);
#endif
}
#else
/*VARARGS2*/
void
log(s,fmt,arg1,arg2,arg3,arg4,arg5)
int s;
char *fmt;
int arg1,arg2,arg3,arg4,arg5;
{
char *cp;
long t;
int fd,i;
struct sockaddr fsocket;
if(Logfp == NULLFILE)
return;
time(&t);
cp = ctime(&t);
rip(cp);
i = SOCKSIZE;
fprintf(Logfp,"%s",cp);
if(getpeername(s,(char *)&fsocket,&i) != -1)
fprintf(Logfp," %s",psocket(&fsocket));
fprintf(Logfp," - ");
fprintf(Logfp,fmt,arg1,arg2,arg3,arg4,arg5);
fprintf(Logfp,"\n");
fflush(Logfp);
#ifdef MSDOS
/* MS-DOS doesn't really flush files until they're closed */
fd = fileno(Logfp);
if((fd = dup(fd)) != -1)
close(fd);
#endif
}
#endif
int
dosource(argc,argv,p)
int argc;
char *argv[];
void *p;
{
int linenum = 0;
char *inbuf,*intmp;
FILE *fp;
/* Read command source file */
if((fp = fopen(argv[1],READ_TEXT)) == NULLFILE){
tprintf(NoRead,argv[1],sys_errlist[errno]);
return 1;
}
inbuf = malloc(BUFSIZ);
intmp = malloc(BUFSIZ);
while(fgets(inbuf,BUFSIZ,fp) != NULLCHAR){
strcpy(intmp,inbuf);
linenum++;
if(Verbose)
tprintf("%s",intmp);
if(cmdparse(Cmds,inbuf,NULL) != 0){
tprintf("*** file \"%s\", line %d: %s\n",
argv[1],linenum,intmp);
}
}
fclose(fp);
free(inbuf);
free(intmp);
return 0;
}
/* if unattended mode is set - restrict ax25, telnet and maybe other sessions */
int
doattended(argc,argv,p)
int argc;
char *argv[];
void *p;
{
return setbool(&Attended,"Attended flag",argc,argv);
}
/* if ThirdParty is not set - restrict the mailbox (S)end command to local only */
int
dothirdparty(argc,argv,p)
int argc;
char *argv[];
void *p;
{
return setbool(&ThirdParty,"Third-Party mail flag",argc,argv);
}
#ifdef ALLCMD
int
domdump(argc,argv,p)
int argc;
char *argv[];
void *p;
{
unsigned int i;
char * addr;
unsigned int len = 8 * 16; /* default is 8 lines of hex dump */
if(argc < 2 || argc > 3) {
tprintf("Usage:- dump <hex-address | .> [decimal-range] \n");
return 0;
}
if(argv[1][0] == '.')
addr = DumpAddr; /* Use last end address */
else
addr = ltop(htol(argv[1])); /* get address of item being dumped */
if(argc == 3) {
len = atoi(argv[2]);
len = ((len + 15) >> 4) << 4; /* round up to modulo 16 */
}
if(len < 1 || len > 256) {
tprintf("Invalid dump range. Valid is 1 to 256\n");
return 0;
}
#ifdef UNIX
tprintf(" Main Memory Dump Of Location %lx\n", FP_SEG(addr));
#else
tprintf(" Main Memory Dump Of Location %Fp\n", addr);
#endif
tprintf("Addr (offset) Hexadecimal Ascii\n");
tprintf("---- ----------- -----\n\n");
for(i = 0; i < len; i += 16)
fmtline((int16)i, (char *)(addr + i), 16);
DumpAddr = (char *)(addr + i); /* update address */
return 0;
}
/* Print a buffer up to 16 bytes long in formatted hex with ascii
* translation, e.g.,
* 0000: 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f 0123456789:;<=>?
*/
static void
fmtline(addr,buf,len)
int16 addr;
char *buf;
int16 len;
{
char line[81];
register char *aptr,*cptr;
register char c;
memset(line,' ',sizeof(line));
ctohex(line,(int16)hibyte(addr));
ctohex(line+2,(int16)lobyte(addr));
aptr = &line[6];
cptr = &line[55];
while(len-- != 0){
c = *buf++;
ctohex(aptr,(int16)uchar(c));
aptr += 3;
c &= 0x7f;
if((c > 0x1f) && (c < 0x7f))
*cptr++ = c;
else
*cptr++ = '.';
}
*cptr++ = '\0';
tprintf("%s\n",line);
}
/* Convert byte to two ascii-hex characters */
static void
ctohex(buf,c)
register char *buf;
register int16 c;
{
static char hex[] = "0123456789abcdef";
*buf++ = hex[hinibble(c)];
*buf = hex[lonibble(c)];
}
#endif
int
dowrite(argc,argv,p)
int argc;
char *argv[];
void *p;
{
int s;
struct mbx *m;
if((s = atoi(argv[1])) == 0) { /* must be a name */
#ifdef MAILBOX
/* check the mailbox users */
for(m=Mbox;m;m=m->next){
if(!strcmp(m->name,argv[1]))
break;
}
if(!m)
return 0;
s = m->user;
#else
return 0;
#endif
}
usprintf(s,"*** Msg from SYSOP: %s\n",argv[2]);
usflush(s);
return 0;
}
#ifdef MAILBOX
/* write a message to all nodeshell users
* argv[1] is the message.
*/
int
dowriteall(argc,argv,p)
int argc;
char *argv[];
void *p;
{
register struct mbx *m;
for(m=Mbox;m;m=m->next){
usprintf(m->user,"*** Msg from SYSOP: %s\n",argv[1]);
usflush(m->user);
}
return 0;
}
#endif
int
dostatus(argc,argv,p)
int argc;
char *argv[];
void *p;
{
time_t nowtime, elapsedtime;
unsigned int days,hrs,mins,secs;
nowtime = time(&nowtime); /* current time */
elapsedtime = nowtime - StartTime; /* nos elapsed time */
tprintf(Nosversion,Version);
tputs(Version2);
tprintf("Tty: %d rows, %d columns\n",Numrows,Numcols);
#ifdef MSDOS
tprintf(NosLoadInfo, _CS, _DS);
#endif
tprintf("\nThe system time is %s", ctime(&nowtime));
tprintf("NOS was started on %s\n", ctime(&StartTime));
secs = elapsedtime % 60;
elapsedtime = elapsedtime / 60;
mins = elapsedtime % 60;
elapsedtime = elapsedtime / 60;
hrs = elapsedtime % 24;
elapsedtime = elapsedtime / 24;
days = elapsedtime;
tprintf("Elapsed time => %u days:%02u hours:%02u minutes:%02u seconds.\n\n",days,hrs,mins,secs);
#ifdef ALLCMD
tprintf("The station is currently %sttended.\n", Attended ? "A" : "Una");
tprintf("The 'Message Of The Day' is ");
if(Motd != NULLCHAR)
tprintf("\n%s",Motd);
else
tprintf("not set!\n");
#endif
#ifdef __TURBOC__
dofstat(); /* print status of open files */
#endif
return 0;
}
#ifdef ALLCMD
int
domotd(argc,argv,p)
int argc;
char *argv[];
void *p;
{
if(argc > 2) {
tprintf("Usage: motd \"<your message>\"\n");
return 1;
}
if(argc < 2) {
if(Motd != NULLCHAR)
tprintf("%s",Motd);
} else {
if(Motd != NULLCHAR){
free(Motd);
Motd = NULLCHAR; /* reset the pointer */
}
if(!strlen(argv[1]))
return 0; /* clearing the buffer */
Motd = mallocw(strlen(argv[1])+5); /* allow for the EOL char etc */
strcpy(Motd, argv[1]);
strcat(Motd, "\n"); /* add the EOL char */
}
return 0;
}
#endif /*ALLCMD*/
#ifdef __TURBOC__
/*
* Fstat utility code.
* Converted to go into NOS by Kelvin Hill - G1EMM April 9, 1990
*/
extern unsigned char _osmajor;
static char *localcopy(char far *);
static char *progname(unsigned int);
int
dofstat()
{
union REGS regs;
struct SREGS segregs;
char far *pfiletab, far * pnext, far * fp;
char far *name, file[13], far * plist, far * entry;
char ownername[9], ownerext[5];
int nfiles, i, j, numhandles, entrylen;
unsigned int access, devinfo, progpsp;
long length, offset;
int heading = 0;
regs.h.ah = 0x52; /* DOS list of lists */
intdosx(®s, ®s, &segregs);
/* make a pointer to start of master list */
plist = (char far *) MK_FP(segregs.es, regs.x.bx);
/* pointer to start of file table */
pfiletab = (char far *) MK_FP(*(int far *) (plist + 6), *(int far *) (plist + 4));
switch (_osmajor) {
case 2:
entrylen = 40; /* DOS 2.x */
break;
case 3:
entrylen = 53; /* DOS 3.x */
break;
case 4:
case 5: /* DOS 5.x - like dos 4.x */
case 6: /* and NOW DOS 6.0 also */
entrylen = 59; /* DOS 4.x - I do not know what is in the
* extra 6 bytes */
break;
default:
/*
tprintf("Sorry, cannot handle this version of MS-DOS");
*/
return 1;
}
for (;;) {
/* pointer to next file table */
pnext = (char far *) MK_FP(*(int far *) (pfiletab + 2), *(int far *) (pfiletab + 0));
nfiles = *(int far *) (pfiletab + 4);
#ifdef DEBUG
tprintf("\nFile table at %Fp entries for %d files\n", pfiletab, nfiles);
#endif
for (i = 0; i < nfiles; i++) {
/*
* cycle through all files, quit when we reach an
* unused entry
*/
entry = pfiletab + 6 + (i * entrylen);
if (_osmajor >= 3) {
name = entry + 32;
strncpy(file, localcopy(name), 11);
file[11] = '\0';
numhandles = *(int far *) (entry + 0);
access = (int) *(char far *) (entry + 2);
length = *(long far *) (entry + 17);
offset = *(long far *) (entry + 21);
devinfo = *(int far *) (entry + 5);
progpsp = *(int far *) (entry + 49);
} else {
name = entry + 4;
strncpy(file, localcopy(name), 11);
file[11] = '\0';
numhandles = (int) *(char far *) (entry + 0);
access = (int) *(char far *) (entry + 1);
length = *(long far *) (entry + 19);
offset = *(long far *) (entry + 36);
devinfo = (int) *(char far *) (entry + 27);
}
if ((strlen(file) > 0) && (numhandles > 0) && !(devinfo & 0x80)) {
if(!heading) {
tprintf("\n");
tprintf(" Table of Open Files.\n");
tprintf(" --------------------\n");
tprintf("Name length offset hnd acc PSP device type/owner\n");
tprintf("---- ------ ------ --- --- --- -----------------\n");
heading++; /* header now printed */
}
tprintf("%8.8s.%3.3s %8ld %8ld %2d ",
file, &file[8], length, offset, numhandles);
switch (access) {
case 0:
tprintf("r ");
break;
case 1:
tprintf("w ");
break;
case 2:
tprintf("rw ");
break;
default:
tprintf(" ");
}
if (_osmajor >= 3)
tprintf("%04X ", progpsp);
else
tprintf("---- ");
tprintf("drive %c: ", 'A' + (devinfo & 0x1F));
if (devinfo & 0x8000)
tprintf("(network) ");
if (_osmajor >= 3) {
/*
* only DOS 3+ can find out
* the name of the program
*/
fnsplit(progname(progpsp), NULL, NULL, ownername, ownerext);
tprintf(" [%s%s]\n", strlwr(ownername), strlwr(ownerext));
} else {
tprintf("\n");
}
}
if (strlen(file) == 0)
return 0;
}
pfiletab = pnext;
}
}
/* Make a copy of a string pointed to by a far pointer */
static char *
localcopy(s)
char far *s;
{
static char localstring[256];
char far *p = s;
char *l = localstring;
int i = 0;
while (*p != NULL && i++ < 255) {
*l++ = *p++;
}
*l = '\0';
return (localstring);
}
/*
* Return a near pointer to a character string with the full path name of the
* program whose PSP is given in the argument. If the argument is invalid,
* this may return gibberish but I don't know how to tell Offset 0x2C in the
* PSP in the segment address of the environment of a program. Beyond the
* last environment string is a null marker, a word count (usually 1), then
* the full pathname of the owner of the environment This only works for DOS
* 3+
*/
static char *
progname(pid)
unsigned int pid;
{
unsigned far *envsegptr; /* Pointer to seg address of
* environment */
char far *envptr; /* Pointer to pid's environment */
unsigned far *envsizeptr; /* Pointer to environment size */
unsigned envsize;/* Size of pid's environment */
unsigned ppid; /* Parent psp address */
/* find the parent process psp at offset 0x16 of the psp */
ppid = *(unsigned far *) MK_FP(pid, 0x16);
/* find the environment at offset 2Ch of the psp */
envsegptr = (unsigned far *) MK_FP(pid, 0x2C);
envptr = (char far *) MK_FP(*envsegptr, 0);
/*
* Make a pointer that contains the size of the environment block.
* Must point back one paragraph (to the environments MCB plus three
* bytes forward (to the MCB block size field).
*/
envsizeptr = (unsigned far *) MK_FP(*envsegptr - 1, 0x3);
envsize = *envsizeptr * 16; /* x 16 turns it into bytes */
while (envsize > 0) {
/* search for end of environment block, or NULL */
while (--envsize && *envptr++);
/*
* Now check for another NULL immediately following the first
* one located and a word count of 0001 following that.
*/
if (!*envptr && *(unsigned far *) (envptr + 1) == 0x1) {
envptr += 3;
break;
}
}
if (envsize > 0) {
/* Owner name found - return it */
return (localcopy(envptr));
} else {
if (pid == ppid) {
/*
* command.com doesn't leave it's name around, but if
* pid = ppid then we know we have a shell
*/
return ("-shell-");
} else {
return ("unknown");
}
}
}
#endif /*__TURBOC__*/
int
doprompt(argc,argv,p)
int argc;
char *argv[];
void *p;
{
return setbool(&DosPrompt,"prompt",argc,argv);
}
/* Command history, see also pc.c - WG7J */
void logcmd(char *cmd) {
struct hist *new;
char *cp;
if(!Maxhistory) /* don't keep history */
return;
/* Get rid of \n; this is also done in cmdparse().
* We HAVE to do this here, since the string is NOT null-terminated when
* it comes from recv_mbuf() !!!! rip() makes it nullterminated.
*/
rip(cmd);
cp = cmd;
while(*cp == ' ' || *cp == '\t')
cp++;
if(!*cp) /* Empty command */
return;
if(Histrysize < Maxhistory) { /* Add new one */
Histrysize++;
if(!Histry) { /* Empty list */
/* Initialize circular linked list */
Histry = mallocw(sizeof(struct hist));
Histry->next = Histry->prev = Histry;
} else {
new = mallocw(sizeof(struct hist));
/* Now link it in */
Histry->next->prev = new;
new->next = Histry->next;
new->prev = Histry;
Histry->next = new;
Histry = new;
}
} else {
/* Maximum number stored already, use the oldest entry */
Histry = Histry->next;
free(Histry->cmd);
}
Histry->cmd = strdup(cp);
}
int
dohistory(int argc,char *argv[],void *p) {
struct hist *h;
int num;
if(argc > 1) {
Maxhistory = atoi(argv[1]);
return 0;
}
tprintf("Max recall %d\n",Maxhistory);
if((h = Histry) == NULL)
return 0;
num = 0;
do {
tprintf("%.2d: %s\n",num++,h->cmd);
h = h->prev;
} while(h != Histry);
return 0;
}
#ifndef UNIX
/* This adds some additional checks to the fopen()
* in the Borland C++ Run Time Library.
* It fixes problem with users trying to open system devices like
* CON, AUX etc and hang a system.
* WG7J, 930205
*/
#undef fopen
FILE _FAR *_Cdecl fopen(const char _FAR *__path, const char _FAR *__mode);
static char *InvalidName[] = {
"NUL",
"CON",
"AUX",
"PRN",
"LPT1",
"LPT2",
"LPT3",
"COM1",
"COM2",
"COM3",
"COM4",
"MOUSE$",
"CLOCK$",
NULLCHAR,
};
FILE *newfopen (const char *filename, const char *type) {
int i;
for(i=0;InvalidName[i] != NULLCHAR;i++)
if(stricmp(InvalidName[i],filename) == 0)
return NULL;
return fopen (filename, type);
}
#endif
#if defined(__TURBOC__) && !defined(__BORLANDC__)
/* N5KNX: TurboC 2.0 lacks _setcursortype(), which we supply here for dorepeat */
void _setcursortype(int style)
{
/* From TurboC++ conio.h: */
#define _NOCURSOR 0
#define _SOLIDCURSOR 1
#define _NORMALCURSOR 2
/* Int 0x10 reg cx codes: */
#define STD_CURSOR 0x0607
#define BLK_CURSOR 0x0006
#define NO_CURSOR 0x2607
union REGS regs;
if (style == _NOCURSOR) regs.x.cx = NO_CURSOR;
else if (style == _SOLIDCURSOR) regs.x.cx = BLK_CURSOR;
else if (style == _NORMALCURSOR) regs.x.cx = STD_CURSOR;
else return;
regs.x.ax = 0x0100; /* set cursor */
int86(0x10, ®s, ®s);
}
#endif
/* Repeat a command - taken from 930104 KA9Q NOS
WA3DSP 1/93
*/
int
dorepeat(argc,argv,p)
int argc;
char *argv[];
void *p;
{
int32 interval;
int ret;
struct session *sp;
if(isdigit(argv[1][0])){
interval = atol(argv[1]);
argc--;
argv++;
} else {
interval = MSPTICK;
}
if((sp = newsession(argv[2],REPEAT,1)) == NULLSESSION){
tprintf("Too many sessions\n");
return 1;
}
_setcursortype(_NOCURSOR);
while(sp==Current){
/* clrscr(); */
/* gotoxy seems to work better - turn cursor off?? */
gotoxy(1,1);
ret = subcmd(Cmds,argc,argv,p);
if(ret != 0 || pause(interval) == -1)
break;
}
_setcursortype(_NORMALCURSOR);
freesession(sp);
return 0;
}